#include "sys_settings.h"

#include <QCheckBox>
#include <QComboBox>
#include <QCoreApplication>
#include <QDebug>
#include <QFileInfo>
#include <QLabel>
#include <QLineEdit>
#include <QMessageBox>
#include <QPushButton>  // For QMessageBox buttons
#include <QShowEvent>
#include <QSpinBox>

#include "ConstData.h"
#include "IniConfig.h"
#include "ModbusManager.h"
#include "Upload.h"
#include "define.h"
#include "global.h"
#include "ui_sys_settings.h"
#include "user.h"
static const QStringList SERIAL_PORTS = {"COM1", "COM2", "COM3", "COM4", "COM5",
                                         "COM6", "COM7", "COM8", "COM9"};
static const QStringList SERIAL_BAUDS = {"4800", "9600", "19200", "38400", "57600", "115200"};
sys_settings::sys_settings(QWidget* parent)
    : QWidget(parent), ui(new Ui::sys_settings), m_isDownloading(false)
{
    ui->setupUi(this);
    ui->lb_version->setText(QString("版本号: %1").arg(APP_VERSION));
    // 串口设置表格
    ui->tableWidget->setShowGrid(false);                                               // 去除网格线
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);   // 拉伸
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);  // 固定
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(4, QHeaderView::Fixed);  // 固定
    ui->tableWidget->horizontalHeader()->setMaximumSectionSize(80);
    ui->tableWidget->setSelectionMode(QAbstractItemView::NoSelection);    // 禁止选择
    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);  // 禁止编辑
    load_serial_settings_ui();
    // 上传设置表格
    ui->tableWidget_ip->setShowGrid(false);
    ui->tableWidget_ip->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->tableWidget_ip->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed);
    ui->tableWidget_ip->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed);
    ui->tableWidget_ip->horizontalHeader()->setMaximumSectionSize(80);
    ui->tableWidget_ip->setSelectionMode(QAbstractItemView::NoSelection);
    ui->tableWidget_ip->setEditTriggers(QAbstractItemView::NoEditTriggers);
    load_upload_settings_ui();

    // Initially hide the progress bar
    ui->updateProgressBar->setVisible(false);
    ui->updateProgressBar->setValue(0);
    ui->updateProgressBar->setTextVisible(true);  // Show percentage text on progress bar

    initUpdateSystem();  // MOVED: Call to the new initialization function
}

sys_settings::~sys_settings() { delete ui; }

// ADDED: New method for update system initialization
void sys_settings::initUpdateSystem()
{
    m_appUpdater = new AppUpdater(APP_ID, APP_VERSION, this);  // Parented to sys_settings

    connect(m_appUpdater, &AppUpdater::updateStatusMessage, this,
            [this](const QString& message) { ui->lb_updateMsg->setText(message); });

    connect(m_appUpdater, &AppUpdater::readyToQuitForUpdate, this, []() {
        qInfo() << "sys_settings: Received readyToQuitForUpdate signal. Quitting application.";
        QCoreApplication::quit();
    });

    connect(m_appUpdater, &AppUpdater::errorOccurred, this, [this](const QString& errorMessage) {
        QMessageBox::warning(this, "更新操作错误", errorMessage);
        ui->lb_updateMsg->setText(QString("更新错误"));

        m_isDownloading = false;
        ui->pb_update->setText("检查更新");
        ui->pb_update->setEnabled(true);
        ui->updateProgressBar->setVisible(false);
    });

    connect(m_appUpdater, &AppUpdater::updateCheckFinished, this,
            [this](bool updateAvailable, const QString& latestVersion, const QString& downloadUrl,
                   const QString& releaseNotes) {
                if (updateAvailable) {
                    QMessageBox msgBox(this);
                    msgBox.setWindowTitle("发现新版本");
                    msgBox.setIcon(QMessageBox::Information);
                    msgBox.setText(
                        QString("最新版本: %1\n\n更新日志:\n%2").arg(latestVersion, releaseNotes));
                    msgBox.setInformativeText(QString("是否立即下载更新？"));
                    QPushButton* downloadButton =
                        msgBox.addButton("立即下载", QMessageBox::AcceptRole);
                    msgBox.addButton("稍后提醒", QMessageBox::RejectRole);

                    if (downloadUrl.isEmpty()) {
                        downloadButton->setEnabled(false);
                    }
                    msgBox.exec();

                    if (msgBox.clickedButton() == downloadButton && !downloadUrl.isEmpty()) {
                        ui->updateProgressBar->setValue(0);
                        ui->updateProgressBar->setRange(0, 0);
                        ui->updateProgressBar->setVisible(true);
                        m_appUpdater->startDownload(downloadUrl);
                    } else {
                        ui->pb_update->setText("检查更新");
                        ui->pb_update->setEnabled(true);
                        m_isDownloading = false;
                    }
                } else {
                    QMessageBox::information(
                        this, "检查更新", QString("您的应用已是最新版本 (%1)。").arg(APP_VERSION));
                    ui->pb_update->setText("检查更新");
                    ui->pb_update->setEnabled(true);
                    m_isDownloading = false;
                }
            });

    connect(m_appUpdater, &AppUpdater::downloadStarted, this, [this](const QString& fileName) {
        m_isDownloading = true;
        ui->pb_update->setText("取消下载");
        ui->pb_update->setEnabled(true);

        ui->lb_updateMsg->setText(QString("开始下载: %1").arg(fileName));
        ui->updateProgressBar->setVisible(true);
        ui->updateProgressBar->setRange(0, 0);
        ui->updateProgressBar->setValue(0);
    });

    connect(m_appUpdater, &AppUpdater::downloadProgress, this,
            [this](qint64 bytesReceived, qint64 bytesTotal) {
                if (!ui->updateProgressBar->isVisible()) {
                    ui->updateProgressBar->setVisible(true);
                }
                if (bytesTotal > 0) {
                    ui->updateProgressBar->setRange(0, bytesTotal);
                    ui->updateProgressBar->setValue(bytesReceived);
                } else {
                    ui->updateProgressBar->setRange(0, 0);
                }
            });

    connect(
        m_appUpdater, &AppUpdater::downloadFinished, this,
        [this](const QString& filePath, bool success, const QString& errorString) {
            m_isDownloading = false;

            ui->updateProgressBar->setVisible(false);
            ui->updateProgressBar->setValue(0);

            if (success) {
                QMessageBox msgBox(this);
                msgBox.setWindowTitle("下载完成");
                msgBox.setIcon(QMessageBox::Question);  // Use Question icon
                msgBox.setText(
                    "更新包已成功下载。是否立即关闭程序并应用更新？");  // Main concise text
                msgBox.setInformativeText(
                    QString("下载路径: %1").arg(filePath));  // Detailed path in informative text
                msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
                msgBox.setDefaultButton(QMessageBox::Yes);

                int ret = msgBox.exec();

                if (ret == QMessageBox::Yes) {  // Check against the standard button role
                    qDebug() << "用户选择立即更新，调用 AppUpdater::installUpdate()";
                    ui->pb_update->setEnabled(false);
                    ui->lb_updateMsg->setText("正在准备应用更新...");
                    if (m_appUpdater) {
                        m_appUpdater->installUpdate();
                    }
                } else {
                    ui->pb_update->setText("检查更新");
                    ui->pb_update->setEnabled(true);
                }
            } else {
                if (!errorString.isEmpty() && errorString != "用户取消了下载") {
                    QMessageBox::critical(this, "下载失败",
                                          QString("下载更新包失败: %1").arg(errorString));
                }
                ui->pb_update->setText("检查更新");
                ui->pb_update->setEnabled(true);
            }
        });
}

void sys_settings::load_serial_settings()
{
    ModbusManager* modbusManager = ModbusManager::instance();
    for (int i = 0; i < DEVICE_NAMES.size(); i++) {
        int row = i;
        MbDeviceConfig config = modbusManager->getDeviceConfig(DEVICE_NAMES[i]);
        QComboBox* cbPort = qobject_cast<QComboBox*>(ui->tableWidget->cellWidget(row, 1));
        QComboBox* cbBaud = qobject_cast<QComboBox*>(ui->tableWidget->cellWidget(row, 2));
        QSpinBox* spinAddr = qobject_cast<QSpinBox*>(ui->tableWidget->cellWidget(row, 3));
        QCheckBox* cbEnable = qobject_cast<QCheckBox*>(ui->tableWidget->cellWidget(row, 4));
        cbPort->setCurrentText(config.portName);
        cbBaud->setCurrentText(QString::number(config.baudRate));
        spinAddr->setValue(config.slaveAddress);
        cbEnable->setChecked(config.enabled);
    }
}
void sys_settings::load_serial_settings_ui()
{
    for (int i = 0; i < DEVICE_NAMES.size(); i++) {
        int row = i;

        // 添加一行
        ui->tableWidget->insertRow(row);
        ui->tableWidget->setRowHeight(row, 30);
        // 设备名称
        QLabel* label = new QLabel(DEVICE_NAMES[i]);
        label->setAlignment(Qt::AlignCenter);
        ui->tableWidget->setCellWidget(row, 0, label);
        label->setFixedHeight(25);
        // 串口号
        QComboBox* cbPort = new QComboBox();
        cbPort->addItems(SERIAL_PORTS);
        ui->tableWidget->setCellWidget(row, 1, cbPort);
        cbPort->setFixedHeight(25);
        // 波特率
        QComboBox* cbBaud = new QComboBox();
        cbBaud->addItems(SERIAL_BAUDS);
        ui->tableWidget->setCellWidget(row, 2, cbBaud);
        cbBaud->setFixedHeight(25);
        // 设备地址
        QSpinBox* spinAddr = new QSpinBox();
        spinAddr->setRange(1, 247);
        spinAddr->setAlignment(Qt::AlignCenter);
        ui->tableWidget->setCellWidget(row, 3, spinAddr);
        spinAddr->setFixedHeight(25);
        // 启用
        QCheckBox* cbEnable = new QCheckBox();
        ui->tableWidget->setCellWidget(row, 4, cbEnable);
        cbEnable->setFixedHeight(25);
    }
    load_serial_settings();
}
void sys_settings::load_upload_settings()
{
    auto config = Upload::Upload::instance()->getConfig();
    for (int i = 0; i < config.size(); i++) {
        int row = i;
        auto key = config.keys()[i];
        auto value = config[key];
        QLineEdit* lineEdit = qobject_cast<QLineEdit*>(ui->tableWidget_ip->cellWidget(row, 0));
        QSpinBox* spinBox = qobject_cast<QSpinBox*>(ui->tableWidget_ip->cellWidget(row, 1));
        QLineEdit* lineEdit_mn = qobject_cast<QLineEdit*>(ui->tableWidget_ip->cellWidget(row, 2));
        QCheckBox* cbEnable = qobject_cast<QCheckBox*>(ui->tableWidget_ip->cellWidget(row, 3));
        lineEdit->setText(value.IP);
        spinBox->setValue(value.port);
        lineEdit_mn->setText(value.MN);
        cbEnable->setChecked(value.enabled);
    }
}
void sys_settings::load_upload_settings_ui()
{
    auto config = Upload::Upload::instance()->getConfig();
    for (int i = 0; i < config.size(); i++) {
        int row = i;
        // 添加一行
        ui->tableWidget_ip->insertRow(row);
        ui->tableWidget_ip->setRowHeight(row, 30);
        // IP地址
        QLineEdit* lineEdit = new QLineEdit();
        lineEdit->setAlignment(Qt::AlignCenter);
        lineEdit->setPlaceholderText("请输入IP地址");
        ui->tableWidget_ip->setCellWidget(row, 0, lineEdit);
        lineEdit->setFixedHeight(25);
        // 端口号
        QSpinBox* spinBox = new QSpinBox();
        spinBox->setRange(1, 65535);
        spinBox->setAlignment(Qt::AlignCenter);
        ui->tableWidget_ip->setCellWidget(row, 1, spinBox);
        spinBox->setFixedHeight(25);
        // MN号
        QLineEdit* lineEdit_mn = new QLineEdit();
        lineEdit_mn->setAlignment(Qt::AlignCenter);
        lineEdit_mn->setPlaceholderText("请输入MN号");
        ui->tableWidget_ip->setCellWidget(row, 2, lineEdit_mn);
        lineEdit_mn->setFixedHeight(25);
        // 启用
        QCheckBox* cbEnable = new QCheckBox();
        ui->tableWidget_ip->setCellWidget(row, 3, cbEnable);
        cbEnable->setFixedHeight(25);
    }
    load_upload_settings();
}
void sys_settings::on_pb_ip_set_clicked()
{
    auto config = Upload::Upload::instance()->getConfig();
    for (int i = 0; i < config.size(); i++) {
        int row = i;
        auto key = config.keys()[i];
        auto value = config[key];
        QLineEdit* lineEdit = qobject_cast<QLineEdit*>(ui->tableWidget_ip->cellWidget(row, 0));
        QSpinBox* spinBox = qobject_cast<QSpinBox*>(ui->tableWidget_ip->cellWidget(row, 1));
        QLineEdit* lineEdit_mn = qobject_cast<QLineEdit*>(ui->tableWidget_ip->cellWidget(row, 2));
        QCheckBox* cbEnable = qobject_cast<QCheckBox*>(ui->tableWidget_ip->cellWidget(row, 3));
        value.IP = lineEdit->text();
        value.port = spinBox->value();
        value.MN = lineEdit_mn->text();
        value.enabled = cbEnable->isChecked();
        config[key] = value;
    }
    bool is_save = Upload::Upload::instance()->setConfig(config);
    if (is_save) {
        showSuccess("上传配置已成功保存");
    } else {
        QMessageBox::warning(this, "保存失败", "上传配置保存失败");
    }
}

void sys_settings::on_pb_serial_set_clicked()
{
    ModbusManager* modbusManager = ModbusManager::instance();
    for (int i = 0; i < DEVICE_NAMES.size(); i++) {
        int row = i;
        QString deviceId = DEVICE_NAMES[i];
        QComboBox* cbPort = qobject_cast<QComboBox*>(ui->tableWidget->cellWidget(row, 1));
        QComboBox* cbBaud = qobject_cast<QComboBox*>(ui->tableWidget->cellWidget(row, 2));
        QSpinBox* spinAddr = qobject_cast<QSpinBox*>(ui->tableWidget->cellWidget(row, 3));
        QCheckBox* cbEnable = qobject_cast<QCheckBox*>(ui->tableWidget->cellWidget(row, 4));
        QString port = cbPort->currentText();
        QString baud = cbBaud->currentText();
        int addr = spinAddr->value();
        bool enable = cbEnable->isChecked();
        MbDeviceConfig config;
        config.name = deviceId;
        config.portName = port;
        config.baudRate = baud.toInt();
        config.slaveAddress = addr;
        config.enabled = enable;
        modbusManager->addDevice(deviceId, config);
    }
    bool is_save = modbusManager->saveConfiguration();
    if (is_save) {
        showSuccess("设备配置已成功保存");
    } else {
        QMessageBox::warning(this, "保存失败", "设备配置保存失败");
    }
}

void sys_settings::setSaveButtonEnabled(bool enabled)
{
    ui->pb_ip_set->setEnabled(enabled);
    ui->pb_serial_set->setEnabled(enabled);
    ui->pb_info_set->setEnabled(enabled);
    ui->pb_update->setEnabled(enabled);
}
void sys_settings::showEvent(QShowEvent* event)
{
    using namespace IniConfigGlobal;
    QWidget::showEvent(event);
    setSaveButtonEnabled(user::isLoggedIn());
    // 每次显示页面时重新加载配置
    load_serial_settings();
    load_upload_settings();
    ui->station_name->setText(getValue(INI_KEY_STATION_NAME, "").toString());
    ui->station_maintenance->setText(getValue(INI_KEY_STATION_MAINTENANCE, "").toString());
}
void sys_settings::on_pb_update_clicked()
{
    if (m_isDownloading) {
        // Action: Cancel Download
        if (m_appUpdater) {
            m_appUpdater->cancelDownload();
        }
    } else {
        // Action: Check for Updates
        ui->pb_update->setEnabled(false);  // Disable while checking
        ui->pb_update->setText("检查中...");
        if (m_appUpdater) {
            m_appUpdater->checkForUpdates();
        } else {
            QMessageBox::critical(this, "错误", "更新组件未初始化。");
            ui->pb_update->setText("检查更新");
            ui->pb_update->setEnabled(true);
        }
    }
}

void sys_settings::on_pb_info_set_clicked()
{
    using namespace IniConfigGlobal;
    setValue(INI_KEY_STATION_NAME, ui->station_name->text());
    setValue(INI_KEY_STATION_MAINTENANCE, ui->station_maintenance->text());
    emit settingsChanged();  // Emit signal to notify settings change
}